package com.yjz.jvm.juc.Semaphore;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;


/**
 * 信号量: 30个线程并发的从某处读取数据写入数据库，但是数据库连接池只有10个,所以需要用Semaphore来限流
 *
 * @author yjz
 */
@Slf4j
public class SemaphoreLearn {

    private static final int THREAD_COUNT = 10;

    private static ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT);

    private static Semaphore s = new Semaphore(2);

    public static void main(String[] args) {
        for (int i = 0; i < THREAD_COUNT; i++) {
            //30个线程并发读取数据
            threadPool.execute(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + " 等待2秒get tickets");
                    Thread.sleep(2000);

                    //只有获取到许可证的线程才能执写入数据库的操作,许可证只有10个，即限流10个线程访问数据库
                    s.acquire();
                    System.out.println(Thread.currentThread().getName() + " get tickets");

                    //业务处理,耗时4秒
                    System.out.println(Thread.currentThread().getName() + " 等待4秒");
                    Thread.sleep(4000);
                    System.out.println(Thread.currentThread().getName() + " 写入数据库");

                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName() + " 等待1秒release tickets");

                    s.release();
                    System.out.println(Thread.currentThread().getName() + " release tickets");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        threadPool.shutdown();
    }

}

